how the simulator work with command and interrupt

the main loop of the simulator is interp().  The loop accepts one line input of command and takes actions according to the command. It runs until "Q" command is issued.

interp()
  runf = 1  
  while runf
    read input
    take action
    T:....
    Q: runf = 0    // quit

There are two ways to run instructions: "T" one step, "G" trace.
trace() executes instructions continuously until "trap stop" or hits the breakpoint (which is set by "B").

trace()
  while not break && runflag && clock < MAXSIM
    runoneclock()

runflag is global. It is used to stop trace().  It is clear (set to 0) by "trap stop".

runoneclock() is the main function that executes one instruction under the environment of IoT board which has interrupts and simulated devices (timers and ports). 

runoneclock()
  clock++         // advance global clock
  simdevices()    // may raise intrq 0..3 (interrupt request)
  if runflag && cpuflag
    run()
  checkinterrupt()

run() decodes each instruction and executes it. cpuflag is used by "wfi" instruction (wait for interrupt) to put cpu into idle mode that just advance the clock without executing any instructions (PC is not advanced). Once interrupt() is executed cpuflag is clear.

how interrupt work

The interrupt cannot be nested.  intflag is a global flag that controls all interrupts.  It is disable once interrupt() starts and will be reset at "reti". So, during Interrupt Service Routine no other interrupt will be accepted.

Each interrupt consists of interrupt mask, intmask 0..3, and interrupt request, intrq 0..3, flags. The instruction ei/di toggle interrupt mask. intrq is raised by devices such as timers.

At the end of each instruction execution, checkinterrupt() handles all interrupts. 

checkinterrupt()
   if intflag          // master int flag
      if intmask && intrq
         do interrupt()

interrupt()            // start the interrupt service routine
   save PC to r31
   set PC to proper vector
   cpuflag = 1
   intflag = 0
   intrq[.] = 0

interrupt() wakes up idle cpu, disable other interrupts and clear the interrupt request. Please note that, intflag will be enable at "reti", therefore during ISR which is started by interrupt() until "reti" no other interrupt is serviced (although the devices can raised intrq).


last update 17 Feb 2026











   